package database.syn;

import java.util.ArrayList;

public class SynonymAttributeTable{
	ListSynonymAtt tableSynonym = new ListSynonymAtt();
	
	/**
	 * ví dụ : Sinhvien.malop = Lop.malop thì malop là synonym 
	 * thì Sinhvien.malop là left Lop.malop là right
	 * @param left
	 * @param right
	 */
	public void addSynonymAttribute(String left, String right) {
		tableSynonym.addSynonymAtt(left, right);
	}
	
	/**
	 * tìm tất cả đồng nghĩa của att
	 * @param att
	 * @return
	 */
	public String[] findSynonymList(String att) {
		return tableSynonym.findSynonymList(att);
	}
	
	
	@SuppressWarnings("serial")
	public class ListSynonymAtt extends ArrayList<Node>{
		/**
		 * ví dụ : Sinhvien.malop = Lop.malop thì malop là synonym 
		 * thì Sinhvien.malop là left Lop.malop là right
		 * @param left
		 * @param right
		 */
		public void addSynonymAtt(String left, String right) {
			Node attLeft = this.findNodeWithSynonymPatern(left);
			Node attRight = this.findNodeWithSynonymPatern(right);
			
			if(attLeft == null && attRight == null) {
				//t?o m?i 2 node và liên k?t chúng l?i v?i nhau
				attLeft = new Node();
				attRight = new Node();
				attLeft.attName = left;
				attRight.attName = right;
				attLeft.nextNode = attRight;
				this.add(attLeft);
			}
			
			if(attLeft == null && attRight != null) {
				//dùng thèng attRight r?i tìm d?n node cu?i cùng. t?o thèng node m?i có attName là left
				//add nó vào cu?i
				while(attRight.nextNode != null) {
					attRight = attRight.nextNode;
				}
				attLeft = new Node();
				attLeft.attName = left;
				attRight.nextNode = attLeft;
			}
			
			if(attLeft != null && attRight == null) {
				//dùng thèng attLeft r?i tìm d?n node cu?i cùng. t?o thèng node m?i có attName là right
				//add nó vào cu?i
				while(attLeft.nextNode != null) {
					attLeft = attLeft.nextNode;
				}
				attRight = new Node();
				attRight.attName = right;
				attLeft.nextNode = attRight;
			}
			
			if(attLeft != null && attRight != null) {
				//ko làm gì c? hehe
			}
		}
		
		public Node findNodeWithSynonymPatern(String patern) {
			for(Node n : this) {
				Node node = n.findNode(patern);
				if(node != null) {
					return n;
				}
			}
			return null;
		}
	
		/**
		 * tìm xem có đồng nghĩa ko? nếu có trả về ArrayList đồng nghĩa.
		 * không thì trả về null.
		 * @param patern
		 * @return
		 */
		public String[] findSynonymList(String patern) {
			ArrayList<String> result = new ArrayList<String>();
			for (Node node : this) {
				if(node.isExistPaternName(patern)) {
					while(node != null) {
						result.add(node.attName);
						node = node.nextNode;
					}
				}
			}
			return castArrayListToString(result);
		}
		
		private String[] castArrayListToString(ArrayList<String> arr) {
			if(arr.isEmpty()) {
				return null;
			}
			String[] result = new String[arr.size()];
			for(int i = 0; i < result.length; i++) {
				result[i] = arr.get(i);
			}
			return result;
		}
	}
	
	private class Node {
		public String attName;
		public Node nextNode;
		/**
		 * hàm để tìm node nếu node đó synonym với att
		 * @param att
		 * @return nếu node này cùng nghĩa với att thì trả về Node đó. ko thì trả về null
		 */
		public Node findNode(String att) {
			if(attName.equals(att)) {
				return this;
			}
			Node p = nextNode;
			while(p.nextNode != null) {
				p = p.nextNode;
				if(p.attName.equals(att)) {
					return p;
				}
			}
			return null;
		}
		public boolean isExistPaternName(String patern) {
			Node p = this;
			while(p != null) {
				if(p.attName.equals(patern)) {
					return true;
				} else {
					p = p.nextNode;
				}
			}
			return false;
		}
	}
}
